﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLite.Collections;
using System.Xml;

namespace NLite.Xml
{
    /// <summary>
    /// 节点接口，主要应用在操作Xml接口
    /// </summary>
    public interface INode
    {
        String Name { get; }
        String Value { get; }
        IList<INode> Nodes { get; }
        IPropertySet Attributes { get; }
    }

    [Serializable]
    public abstract class Node : INode
    {
        protected String internalName;
        protected String internalValue;
        private PropertySet attributes;
        private List<INode> children = new List<INode>();

        protected Node()
        {
            attributes = new PropertySet();
        }

        protected Node(StringComparer comparer)
        {
            attributes = new PropertySet(comparer);
        }

        public virtual String Name
        {
            get { return internalName; }
        }

        public virtual String Value
        {
            get { return internalValue; }
        }

        public virtual IList<INode> Nodes
        {
            get { return children; }

        }

        public virtual IPropertySet Attributes
        {
            get { return attributes; }

        }

        //public virtual object GetValue(Type type, object defaultValue)
        //{

        //    try
        //    {
        //        var value = Mapper.Map(internalValue, Types.String, type);
        //        if (value == null)
        //            return defaultValue;
        //        return value;
        //    }
        //    catch (Exception)
        //    {
        //        return defaultValue;
        //    }
        //}
    }


    /// <summary>
    /// 文档，对应于XmlDocument
    /// </summary>
    [Serializable]
    public class Document : Node
    {

        public Document(string name, string value)
            : base()
        {
            this.internalName = name;
            this.internalValue = value;
        }


        public Document(XmlNode node)
            : base(StringComparer.OrdinalIgnoreCase)
        {
            this.internalName = node.LocalName;
            this.internalValue = node.InnerText;

            if (node.Attributes != null)
                foreach (XmlAttribute attr in node.Attributes)
                    Attributes[attr.LocalName] = attr.InnerText;

            foreach (XmlNode child in node.ChildNodes)
            {
                if (child.NodeType != XmlNodeType.Element)
                    continue;

                Nodes.Add(new Document(child));
            }
        }
    }
}
